﻿#region Using directives
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using AlphaMobileControls;
using gpsMe.Utils;
using gpsMe.Properties;
using gpsMe.UI.Components;
using gpsMe.Classes;
using System.Threading;
using gpsMe.GPS;
#endregion

namespace gpsMe.UI.Forms
{
    /// <summary>
    /// Main Form of gpsMe
    /// </summary>
    public partial class gpsMeMainForm : AlphaForm
    {
        #region Instance
        /// <summary>
        /// Current gpsMeMainFormInstance
        /// </summary>
        public static gpsMeMainForm Instance { get; private set; }
        #endregion

        #region Controls
        /// <summary>
        /// Background PictureBox
        /// </summary>
        private AlphaPictureBox backgroundPictureBox;

        /// <summary>
        /// Logo PictureBox
        /// </summary>
        private AlphaPictureBox logoPictureBox;

        /// <summary>
        /// Loading progress bar
        /// </summary>
        private gpsMeAlphaProgressBar progressBar;

        /// <summary>
        /// Loading label that displays current state
        /// </summary>
        private AlphaLabel loadingLabel;
        #endregion

        #region Attributes
        /// <summary>
        /// Index of the loading state
        /// </summary>
        private int loadinglabelIndex = 0;

        /// <summary>
        /// specifies if the properties are loaded
        /// </summary>
        private bool propertiesLoaded = false;

        /// <summary>
        /// Thread that updates the loading informations
        /// </summary>
        private static Thread loadingInfoUpdateThread;

        /// <summary>
        /// Event handler allowing us to acces form's properties
        /// </summary>
        private event EventHandler loadingInfoUpdateEventHandler;
        #endregion

        #region Constructor
        /// <summary>
        /// Main form default constructor
        /// </summary>
        public gpsMeMainForm()
        {
            Instance = this;
            #region Form Initialization
            InitializeComponent();
            this.SuspendLayout();

            #region Background PictureBox initialization
            this.backgroundPictureBox = new AlphaPictureBox();
            this.backgroundPictureBox.Location = new Point(0, 0);
            this.backgroundPictureBox.Size = this.ClientSize;
            this.backgroundPictureBox.Image = AlphaImage.CreateFromFile(gpsMeUtils.ApplicationDirectory + @"\Images\loadingBackground.png");
            #endregion

            #region Logo PictureBox initialization
            this.logoPictureBox = new AlphaPictureBox();
            this.logoPictureBox.Image = AlphaImage.CreateFromFile(gpsMeUtils.ApplicationDirectory + @"\Images\gpsMeLogo.png");
            this.logoPictureBox.Size = new Size(gpsMeMainFormProperties.GPSME_LOGO_WIDTH, gpsMeMainFormProperties.GPSME_LOGO_HEIGHT);
            this.logoPictureBox.Location = new Point((ClientSize.Width - this.logoPictureBox.Width) / 2, ClientSize.Height / 10);
            #endregion

            #region Progressbar initialization
            this.progressBar = new gpsMeAlphaProgressBar(gpsMeUtils.ApplicationDirectory + @"\Images\progressBarBackground.png", gpsMeUtils.ApplicationDirectory + @"\Images\progressBarForeground.png");
            this.progressBar.Location = new Point((ClientSize.Width - gpsMeMainFormProperties.GPSME_PROGRESS_BAR_WIDTH) / 2, (ClientSize.Height / 10) * 8);
            this.progressBar.Size = new Size(gpsMeMainFormProperties.GPSME_PROGRESS_BAR_WIDTH, gpsMeMainFormProperties.GPSME_PROGRESS_BAR_HEIGHT);
            this.progressBar.Value = 5;
            #endregion

            #region Loading label initialization
            this.loadingLabel = new AlphaLabel();
            this.loadingLabel.Width = this.ClientSize.Width;
            if (this.ClientSize.Width > this.ClientSize.Height)
                this.loadingLabel.Location = new Point(gpsMeMainFormProperties.GPSME_LOADING_LABEL_LEFT_WIDE_POSITIONS[0], (ClientSize.Height / 10) * 6);
            else
                this.loadingLabel.Location = new Point(gpsMeMainFormProperties.GPSME_LOADING_LABEL_LEFT_POSITIONS[0], (ClientSize.Height / 10) * 6);
            this.loadingLabel.ForeColor = Color.White;
            this.loadingLabel.Text = gpsMeLanguage.Instance.LoadingLabel;
            #endregion

            #region Controls attachment
            this.Controls.Add(this.logoPictureBox);
            this.Controls.Add(this.progressBar);
            this.Controls.Add(this.loadingLabel);
            this.Controls.Add(this.backgroundPictureBox);
            #endregion

            this.ResumeLayout(false);

            #region Form Listeners Initialization */
            this.Resize += new EventHandler(gpsMeMainForm_Resize);
            this.GotFocus += new EventHandler(gpsMeMainForm_GotFocus);
            #endregion

            this.progressBar.Visible = false;// Currently invisible due to estethics and time reasons
            #endregion
            this.progressBar.Value = 10; // End of the form init, progressbar goes to 10%
        }
        #endregion

        #region Functions / Methods / Events
        /// <summary>
        /// Invoked after the loading of the form
        /// </summary>
        /// <param name="p_oSender"></param>
        /// <param name="p_oEventArgs"></param>
        private void gpsMeMainForm_GotFocus(object p_oSender, EventArgs p_oEvenArgs)
        {
            loadingInfoUpdateThread = new Thread(new ThreadStart(this.LoadingInfoUpdateThreadLoop));
            loadingInfoUpdateThread.Start();
        }

        /// <summary>
        /// Method invoked when the screen size has changed
        /// </summary>
        /// <param name="p_oSender"></param>
        /// <param name="p_oEventArgs"></param>
        private void gpsMeMainForm_Resize(object p_oSender, EventArgs p_oEventArgs)
        {
            /* Background resizing */
            this.backgroundPictureBox.Location = new Point(0, 0);
            this.backgroundPictureBox.Size = this.ClientSize;
            /* Logo repositionning */
            this.logoPictureBox.Location = new Point((ClientSize.Width - this.logoPictureBox.Width) / 2, ClientSize.Height / 10);
            /* ProgressBar repositionning */
            this.progressBar.Location = new Point((ClientSize.Width - 400) / 2, (ClientSize.Height / 10) * 8);
            /* Loading label repositionning */
            if (this.ClientSize.Width > this.ClientSize.Height)
                this.loadingLabel.Location = new Point(gpsMeMainFormProperties.GPSME_LOADING_LABEL_LEFT_WIDE_POSITIONS[this.loadinglabelIndex], (ClientSize.Height / 10) * 6);
            else
                this.loadingLabel.Location = new Point(gpsMeMainFormProperties.GPSME_LOADING_LABEL_LEFT_POSITIONS[this.loadinglabelIndex], (ClientSize.Height / 10) * 6);
        }

        /// <summary>
        /// Loads properties, maps, cursors and more from xml files
        /// Also updates the label & progress bar in function of the loading status
        /// </summary>
        /// <returns>Loading success</returns>
        private bool LoadProperties()
        {
            try
            {
                this.progressBar.Value = 15;
                #region Properties Loading
                this.loadingLabel.Text = gpsMeLanguage.Instance.LoadingPropertiesXmlField;
                try
                {
                    new gpsMeProperties(gpsMeUtils.ApplicationDirectory + @"\properties.xml");
                }
                catch
                {
                    MessageBox.Show(gpsMeLanguage.Instance.ErrorPropertiesFileNotFoundField);
                    this.Close();
                }
                if (gpsMeProperties.Instance.PropertiesVersion != gpsMeProperties.CURRENT_GPSMEPROPERTIES_VERSION)
                {
                    MessageBox.Show(gpsMeLanguage.Instance.ErrorPropertiesVersionNotSupportedField);
                    this.Close();
                }
                #endregion

                this.progressBar.Value = 25;

                #region Optimizer init
                new gpsMeOptimizer();
                #endregion

                this.loadingLabel.Text = gpsMeLanguage.Instance.LoadingGpsMeInterfaceField;
                this.progressBar.Value = 50;

                //new gpsMeGpsProvider();
                this.progressBar.Value = 75;

                this.progressBar.Value = 
                this.progressBar.Value = 100;
                return true;
            }
            catch
            {
                return false;
            }
        }

        /// <summary>
        /// Loop of the loadingInfoUpdate thread
        /// </summary>
        private void LoadingInfoUpdateThreadLoop()
        {
            Thread.Sleep(2000);
            Invoke(new gpsMeUtils.MethodInvoker(delegate()
            {
                if (this.LoadProperties())
                {
                    new gpsMeMainMenuForm();
                    gpsMeMainMenuForm.Instance.Show();
                }
                else
                {
                    this.Close();
                }
                this.propertiesLoaded = true;
            }));
            loadingInfoUpdateThread.Abort();
        }
        #endregion
    }
}